import 'dart:io' show Platform;
import 'dart:async';
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:connectivity_plus/connectivity_plus.dart';

import '../http/http_agent.dart';
import '../model/contract_list_model.dart';
import '../service/analytics_service.dart';
import 'contract_controller.dart';
import 'auth_controller.dart';
import 'home_controller.dart';
// ca-app-pub-3940256099942544/5224354917
class AdMobController extends GetxController {
  // Android 广告单元ID
  static const String FREE_PLAN_AD_UNIT_ANDROID =
      'ca-app-pub-7101138379455307/5462381481';
  static const String RUNNING_PLAN_AD_UNIT_ANDROID =
      'ca-app-pub-7101138379455307/3775429481';

  // iOS 广告单元ID
  static const String FREE_PLAN_AD_UNIT_IOS =
      'ca-app-pub-7101138379455307/2731582146'; // 替换为实际的iOS广告单元ID
  static const String RUNNING_PLAN_AD_UNIT_IOS =
      'ca-app-pub-7101138379455307/2731582146'; // 替换为实际的iOS广告单元ID

  // 根据平台获取广告单元ID
  static String get FREE_PLAN_AD_UNIT =>
      Platform.isAndroid ? FREE_PLAN_AD_UNIT_ANDROID : FREE_PLAN_AD_UNIT_IOS;

  static String get RUNNING_PLAN_AD_UNIT => Platform.isAndroid
      ? RUNNING_PLAN_AD_UNIT_ANDROID
      : RUNNING_PLAN_AD_UNIT_IOS;

  // 使用Map存储不同广告单元的广告实例
  final Map<String, RewardedAd?> _rewardedAds = {};
  // 使用Map存储不同广告单元的准备状态
  final Map<String, RxBool> _isRewardedAdReadyMap = {};
  // 使用Map存储不同广告单元的加载尝试次数
  final Map<String, int> _loadAttemptsMap = {};
  // 使用Map存储不同广告单元的加载状态
  final Map<String, RxBool> _isLoadingMap = {};
  // 使用Map存储不同广告单元的上次加载时间
  final Map<String, DateTime> _lastLoadTimeMap = {};

  final RxBool isSubscribing = false.obs;
  final RxBool isDialogShowing = false.obs;

  // 网络连接状态
  final RxBool isConnected = true.obs;
  late StreamSubscription<ConnectivityResult> _connectivitySubscription;

  // 广告加载最小间隔时间（毫秒）
  static const int minLoadIntervalMs = 1000;

  // 获取指定广告单元的准备状态
  bool isRewardedAdReady(String adUnitId) {
    return _isRewardedAdReadyMap[adUnitId]?.value ?? false;
  }

  static const int maxFailedLoadAttempts = 3;

  @override
  void onInit() {
    super.onInit();

    // 初始化网络连接监听
    _initConnectivity();
    _connectivitySubscription =
        Connectivity().onConnectivityChanged.listen(_updateConnectionStatus);
        
    _initConsent();

    // 使用内置 API 配置广告请求参数（替代旧 UMP 同意流程）
    MobileAds.instance.updateRequestConfiguration(
      RequestConfiguration(
        tagForChildDirectedTreatment: TagForChildDirectedTreatment.unspecified,
        tagForUnderAgeOfConsent: TagForUnderAgeOfConsent.unspecified,
        maxAdContentRating: MaxAdContentRating.pg,
      ),
    ).then((_) {
      MobileAds.instance.initialize().then((InitializationStatus status) {
        // 初始化所有广告单元的状态
        _initAdUnitStatus(FREE_PLAN_AD_UNIT);
        // _initAdUnitStatus(RUNNING_PLAN_AD_UNIT);
      });
    });
  }

  @override
  void onClose() {
    _connectivitySubscription.cancel();
    // 释放所有广告资源
    _rewardedAds.forEach((adUnitId, ad) {
      ad?.dispose();
    });
    _rewardedAds.clear();
    super.onClose();
  }

  // 初始化网络连接状态
  Future<void> _initConnectivity() async {
    late ConnectivityResult result;
    try {
      result = await Connectivity().checkConnectivity();
    } catch (e) {
      print('无法检查网络连接状态: $e');
      return;
    }

    _updateConnectionStatus(result);
  }

  // 更新网络连接状态
  void _updateConnectionStatus(ConnectivityResult result) {
    isConnected.value = result != ConnectivityResult.none;

    // 如果网络恢复连接，尝试重新加载未准备好的广告
    if (isConnected.value) {
      _reloadAdsIfNeeded();
    }
  }

  // 重新加载需要的广告
  void _reloadAdsIfNeeded() {
    _isRewardedAdReadyMap.forEach((adUnitId, isReady) {
      if (isReady.value == false && _rewardedAds[adUnitId] == null) {
        _loadRewardedAd(adUnitId);
      }
    });
  }

  // 公共方法：加载指定广告单元的广告
  void loadRewardedAd(String adUnitId) {
    _loadRewardedAd(adUnitId);
  }

  // 广告加载状态
  final RxBool isLoadingAd = false.obs;
  final RxString loadingAdMessage = ''.obs;

  // 显示加载状态提示
  void _showLoadingStatus(String message) {
    loadingAdMessage.value = message;
    isLoadingAd.value = true;
  }

  // 隐藏加载状态提示
  void _hideLoadingStatus() {
    isLoadingAd.value = false;
    loadingAdMessage.value = '';
  }

  // 初始化指定广告单元的状态
  void _initAdUnitStatus(String adUnitId) {
    _isRewardedAdReadyMap[adUnitId] = false.obs;
    _loadAttemptsMap[adUnitId] = 0;
    _isLoadingMap[adUnitId] = false.obs;
    _lastLoadTimeMap[adUnitId] = DateTime.fromMillisecondsSinceEpoch(0);
  }

  // 预加载下一条广告
  void _preloadNextAd(String adUnitId) async {
    // 如果已经有广告在加载或已经准备好，则不重复加载
    if (_rewardedAds[adUnitId] != null &&
        _isRewardedAdReadyMap[adUnitId]?.value == true) {
      return;
    }

    // 如果当前正在加载中，不重复加载
    if (_isLoadingMap[adUnitId]?.value == true) {
      print('Ad is already loading for unit: $adUnitId');
      return;
    }

    // 检查是否满足最小加载间隔
    final now = DateTime.now();
    final lastLoadTime =
        _lastLoadTimeMap[adUnitId] ?? DateTime.fromMillisecondsSinceEpoch(0);
    if (now.difference(lastLoadTime).inMilliseconds < minLoadIntervalMs) {
      print('Too frequent ad load requests for unit: $adUnitId, skipping');
      return;
    }

    // 检查网络连接状态
    if (!isConnected.value) {
      print('Network unavailable, cannot preload next ad');
      return;
    }

    print('Preloading next ad for unit: $adUnitId');
    _isLoadingMap[adUnitId]?.value = true;
    _lastLoadTimeMap[adUnitId] = now;

    final request = await _buildAdRequest();

    // 静默加载，不显示加载状态
    RewardedAd.load(
      adUnitId: adUnitId,
      request: request,
      rewardedAdLoadCallback: RewardedAdLoadCallback(
        onAdLoaded: (ad) {
          _rewardedAds[adUnitId] = ad;
          _isRewardedAdReadyMap[adUnitId]?.value = true;
          _loadAttemptsMap[adUnitId] = 0;
          _isLoadingMap[adUnitId]?.value = false;
          _rewardedAds[adUnitId]!.setServerSideOptions(
            ServerSideVerificationOptions(
              userId: HttpAgent().uid ?? "0", // 用户唯一ID
              customData: 'google_mobile_ads', // 可选
            ),
          );
          print('Next rewarded ad preloaded successfully for unit: $adUnitId');
        },
        onAdFailedToLoad: (error) {
          print(
              'Failed to preload next rewarded ad for unit $adUnitId: ${error.message}');
          _isRewardedAdReadyMap[adUnitId]?.value = false;
          _loadAttemptsMap[adUnitId] = (_loadAttemptsMap[adUnitId] ?? 0) + 1;
          _isLoadingMap[adUnitId]?.value = false;

          // 预加载失败时不显示错误提示，会在广告关闭时再次尝试加载
        },
      ),
    );
  }

  // 加载指定广告单元的广告
  void _loadRewardedAd(String adUnitId) async {
    // 如果已经有广告在加载或已经准备好，则不重复加载
    if (_rewardedAds[adUnitId] != null) {
      return;
    }

    // 如果当前正在加载中，不重复加载
    if (_isLoadingMap[adUnitId]?.value == true) {
      print('Ad is already loading for unit: $adUnitId');
      return;
    }

    // 检查是否满足最小加载间隔
    final now = DateTime.now();
    final lastLoadTime =
        _lastLoadTimeMap[adUnitId] ?? DateTime.fromMillisecondsSinceEpoch(0);
    if (now.difference(lastLoadTime).inMilliseconds < minLoadIntervalMs) {
      print(
          'Too frequent ad load requests for unit: $adUnitId, will retry later');
      Future.delayed(Duration(milliseconds: minLoadIntervalMs),
          () => _loadRewardedAd(adUnitId));
      return;
    }

    // 检查网络连接状态
    if (!isConnected.value) {
      Get.snackbar(
        'Tips',
        'Network connection unavailable, please check your network settings and try again',
        snackPosition: SnackPosition.BOTTOM,
        backgroundColor: Colors.red.withOpacity(0.8),
        colorText: Colors.white,
        duration: Duration(seconds: 2),
      );
      return;
    }

    _showLoadingStatus('Loading Ad...');
    _isLoadingMap[adUnitId]?.value = true;
    _lastLoadTimeMap[adUnitId] = now;

    final request = await _buildAdRequest();

    RewardedAd.load(
      adUnitId: adUnitId,
      request: request,
      rewardedAdLoadCallback: RewardedAdLoadCallback(
        onAdLoaded: (ad) {
          _rewardedAds[adUnitId] = ad;
          _isRewardedAdReadyMap[adUnitId]?.value = true;
          _loadAttemptsMap[adUnitId] = 0;
          _isLoadingMap[adUnitId]?.value = false;
          _rewardedAds[adUnitId]!.setServerSideOptions(
            ServerSideVerificationOptions(
              userId: HttpAgent().uid ?? "0", // 用户唯一ID
              customData: HttpAgent().androidid ?? "0", // 可选
            ),
          );
          print('Rewarded ad loaded for unit: $adUnitId');
          _hideLoadingStatus();
        },
        onAdFailedToLoad: (error) {
          print(
              'Failed to load rewarded ad for unit $adUnitId: ${error.message}');
          _isRewardedAdReadyMap[adUnitId]?.value = false;
          _loadAttemptsMap[adUnitId] = (_loadAttemptsMap[adUnitId] ?? 0) + 1;
          _isLoadingMap[adUnitId]?.value = false;

          if ((_loadAttemptsMap[adUnitId] ?? 0) < maxFailedLoadAttempts) {
            _hideLoadingStatus();
            _showLoadingStatus('Loading Ads...');
            // 使用指数退避策略，失败后等待时间逐渐增加
            final retryDelay = 2000 * (1 << (_loadAttemptsMap[adUnitId] ?? 0));
            Future.delayed(Duration(milliseconds: retryDelay),
                () => _loadRewardedAd(adUnitId));
          } else {
            _hideLoadingStatus();

            AnalyticsService.logEvent(
          name: 'app_load_ad_failed',
          parameters: {
            'platform': Platform.operatingSystem,
            'ad_unit_id': adUnitId,
          },
        );
            // Get.snackbar(
            //   'Tips',
            //   'Ad failed to load after multiple attempts. Please try again later.',
            //   snackPosition: SnackPosition.BOTTOM,
            //   backgroundColor: Colors.red.withOpacity(0.8),
            //   colorText: Colors.white,
            //   duration: Duration(seconds: 2),
            // );
          }
        },
      ),
    );
  }

  /// 展示指定广告单元的激励广告
  void showRewardedAd({
    required OnUserEarnedRewardCallback onUserEarnedReward,
    String? adUnitId, // 不再使用默认值，在方法内部处理
  }) {
    // 如果未指定广告单元ID，则使用FREE_PLAN_AD_UNIT
    final String adUnitIdToUse = adUnitId ?? FREE_PLAN_AD_UNIT;
    // 检查网络连接状态
    if (!isConnected.value) {
      Get.snackbar(
        'Tips',
        'Network connection unavailable, please check your network settings and try again',
        snackPosition: SnackPosition.BOTTOM,
        backgroundColor: Colors.red.withOpacity(0.8),
        colorText: Colors.white,
        duration: Duration(seconds: 2),
      );
      return;
    }

    final isReady = _isRewardedAdReadyMap[adUnitIdToUse]?.value ?? false;
    final ad = _rewardedAds[adUnitIdToUse];

    if (!isReady || ad == null) {
      print('Rewarded ad not ready for unit: $adUnitIdToUse');
      if (!isDialogShowing.value) {
        _showMiningSubscribeDialog(Get.context!);
      }
      return;
    }

    ad.fullScreenContentCallback = FullScreenContentCallback(
      onAdShowedFullScreenContent: (ad) {
        print('Rewarded ad shown for unit: $adUnitIdToUse');
        // 广告显示后立即开始预加载下一条广告
        _preloadNextAd(adUnitIdToUse);
      },
      onAdDismissedFullScreenContent: (ad) {
        print('Rewarded ad dismissed for unit: $adUnitIdToUse');
        ad.dispose();
        _isRewardedAdReadyMap[adUnitIdToUse]?.value = false;
        _rewardedAds[adUnitIdToUse] = null;

        // 如果预加载失败或尚未完成，在这里再次尝试加载
        if (!(_isRewardedAdReadyMap[adUnitIdToUse]?.value ?? false)) {
          _loadRewardedAd(adUnitIdToUse);
        }

        // 检查总算力是否为0，如果是则刷新首页数据
        try {
          final homeController = Get.find<HomeController>();
          // if (homeController.btcTotalPower == 0) {
          //   print('检测到总算力为0，自动刷新首页数据');
          
          // }
            homeController.getHomeData();
        } catch (e) {
          print('检查总算力时出错: $e');
        }

        AnalyticsService.logEvent(
          name: 'app_show_ad',
          parameters: {
            'platform': Platform.operatingSystem,
            'ad_unit_id': adUnitIdToUse,
          },
        );
      },
      onAdFailedToShowFullScreenContent: (ad, error) {
        print(
            'Failed to show rewarded ad for unit $adUnitIdToUse: ${error.message}');
        ad.dispose();
        _isRewardedAdReadyMap[adUnitIdToUse]?.value = false;
        _rewardedAds[adUnitIdToUse] = null;
        _loadRewardedAd(adUnitIdToUse);

        if (!isDialogShowing.value) {
          _showMiningSubscribeDialog(Get.context!);
        }
      },
    );

    ad.show(onUserEarnedReward: onUserEarnedReward);
    _isRewardedAdReadyMap[adUnitIdToUse]?.value = false;
  }

  void showBuyDialog() {
    if (!isDialogShowing.value) {
      _showMiningSubscribeDialog(Get.context!);
    }
  }

  void _showMiningSubscribeDialog(BuildContext context) {
    if (isDialogShowing.value) return;

    isDialogShowing.value = true;

    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) {
        return Obx(() => Stack(
              children: [
                Dialog(
                  backgroundColor: const Color(0xFF1F1F1F),
                  insetPadding:
                      const EdgeInsets.symmetric(horizontal: 28, vertical: 24),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(18),
                  ),
                  child: Padding(
                    padding: const EdgeInsets.fromLTRB(20, 20, 20, 16),
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        // Top icon
                        const Icon(Icons.cloud_outlined,
                            size: 56, color: Colors.orangeAccent),
                        const SizedBox(height: 12),

                        // Title
                        const Text(
                          'Ads Unavailable Right Now',
                          textAlign: TextAlign.center,
                          style: TextStyle(
                            fontSize: 20,
                            height: 1.25,
                            fontWeight: FontWeight.w700,
                            color: Colors.white,
                          ),
                        ),
                        const SizedBox(height: 10),

                        // Body text
                        Text(
                          'We\'re experiencing temporary issues loading ads. Please try again later.\n\n'
                          'Don’t worry—your mining plan is still running and earning rewards for you in our cloud servers.',
                          textAlign: TextAlign.center,
                          style: TextStyle(
                            fontSize: 14,
                            height: 1.5,
                            color: Colors.white.withOpacity(0.8),
                          ),
                        ),
                        const SizedBox(height: 16),

                      

                        const SizedBox(height: 18),
                        const Divider(color: Color(0x22FFFFFF), height: 1),
                        const SizedBox(height: 14),

                        // Bottom single button
                        SizedBox(
                          width: double.infinity,
                          child: ElevatedButton(
                            onPressed: () {
                              isDialogShowing.value = false;
                              Get.back();
                            },
                            style: ElevatedButton.styleFrom(
                              backgroundColor: const Color(0xFF2D2D2D),
                              foregroundColor: Colors.white,
                              elevation: 0,
                              padding: const EdgeInsets.symmetric(vertical: 12),
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(12),
                              ),
                            ),
                            child: const Text('Try Again Later'),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),

                // Fullscreen loading overlay
                if (isSubscribing.value)
                  Container(
                    color: Colors.black.withOpacity(0.6),
                    alignment: Alignment.center,
                    child: const SizedBox(
                      width: 36,
                      height: 36,
                      child: CircularProgressIndicator(),
                    ),
                  ),
              ],
            ));
      },
    ).then((_) {
      isDialogShowing.value = false;
      isSubscribing.value = false;
    });
  }

  // 确保广告已加载，如果未加载则尝试加载
  Future<bool> ensureAdReady(String adUnitId) async {
    if (isRewardedAdReady(adUnitId)) {
      return true;
    }

    // 检查网络连接状态
    if (!isConnected.value) {
      Get.snackbar(
        'Tips',
        'Network connection unavailable, please check your network settings and try again',
        snackPosition: SnackPosition.BOTTOM,
        backgroundColor: Colors.red.withOpacity(0.8),
        colorText: Colors.white,
        duration: Duration(seconds: 2),
      );
      return false;
    }

    showBuyDialog();

    // 如果广告未准备好，尝试加载
    _loadRewardedAd(adUnitId);

    // 等待最多5秒，检查广告是否加载完成
    int attempts = 0;
    while (attempts < 10) {
      await Future.delayed(Duration(milliseconds: 500));
      if (isRewardedAdReady(adUnitId)) {
        return true;
      }
      attempts++;
    }

    return false;
  }


  // Consent helpers kept inside AdMobController
  // 基于 UMP 获取用户隐私同意，并在需要时展示表单（google_mobile_ads 内置 API）
  Future<void> _initConsent() async {
    final params = ConsentRequestParameters();
    ConsentInformation.instance.requestConsentInfoUpdate(
      params,
      () async {
        ConsentForm.loadAndShowConsentFormIfRequired((FormError? loadError) {
          if (loadError != null) {
            print('加载/展示隐私表单失败: ${loadError.errorCode} ${loadError.message}');
          }
        });
      },
      (FormError error) {
        print('更新同意信息失败: ${error.errorCode} ${error.message}');
      },
    );
  }

  // 根据当前同意状态构建广告请求（未取得同意时使用非个性化广告）
  Future<AdRequest> _buildAdRequest() async {
    final status = await ConsentInformation.instance.getConsentStatus();
    final nonPersonalized = status != ConsentStatus.obtained;
    return AdRequest(nonPersonalizedAds: nonPersonalized);
  }

  // 撤销（重置）隐私同意，并再次触发同意流程
  Future<bool> resetPrivacyConsent() async {
    try {
      await ConsentInformation.instance.reset();
      await _initConsent();
      return true;
    } catch (e) {
      print('重置隐私同意失败: $e');
      return false;
    }
  }
}
